from datetime import datetime
from app.models.risk import RiskRule
from app.services.broker import dry_run
from app.core.ws_pool import connected   # WebSocket 集合

RULE = RiskRule()          # 先读默认，后续可 DB

def calc_drawdown(nav_series: list[float]) -> float:
    peak = max(nav_series)
    return (peak - nav_series[-1]) / peak

def check_risk(portfolio: dict[str, int], current_nav: float,
               nav_hist: list[float], industry: dict[str, str]):
    alerts = []
    # 1. 最大回撤
    dd = calc_drawdown(nav_hist)
    if dd > RULE.max_drawdown:
        alerts.append(f"DrawDown {dd:.2%} > {RULE.max_drawdown:.2%}")

    # 2. 单票仓位
    total = sum(portfolio.values())
    for code, qty in portfolio.items():
        ratio = qty / total
        if ratio > RULE.single_pos_ratio:
            alerts.append(f"{code} ratio {ratio:.2%} > {RULE.single_pos_ratio:.2%}")

    # 3. 行业暴露
    ind_map = {}
    for code, qty in portfolio.items():
        ind = industry.get(code, '未知')
        ind_map[ind] = ind_map.get(ind, 0) + qty
    for ind, qty in ind_map.items():
        if qty / total > RULE.industry_ratio:
            alerts.append(f"Industry {ind} {qty/total:.2%} > {RULE.industry_ratio:.2%}")

    return alerts

# 假组合：代码 -> 持股数
FAKE_PORT = {'sz000001': 5000, 'sz000002': 3000, 'sh600519': 1000}
FAKE_NAV  = [100000]                      # 初始净值 10w
FAKE_IND  = {'sz000001': '金融', 'sz000002': '地产', 'sh600519': '白酒'}

def update_nav(new_nav: float):
    FAKE_NAV.append(new_nav)
    alerts = check_risk(FAKE_PORT, new_nav, FAKE_NAV, FAKE_IND)
    if alerts:
        send_risk_alert(alerts)

def send_risk_alert(alerts: list[str]):
    msg = {"type": "risk", "alerts": alerts, "ts": datetime.now().isoformat()}
    for ws in connected:
        ws.send_text(json.dumps(msg))